#pragma once

#include <iostream>
#include <random>
#include <sstream>
#include <stdexcept>
#include <string>
#include <thread>
#include <tuple>
#include <chrono>
#include <vector>
#include <fstream>
#include <sstream>
#include <cstring>
#include <functional>
#include <memory>

#include "carla/client/Client.h"
#include "carla/trafficmanager/TrafficManager.h"
#include "carla/client/BlueprintLibrary.h"
#include "carla/client/Map.h"
#include "carla/client/World.h"
#include "carla/image/ImageIO.h"
#include "carla/image/ImageView.h"
#include "carla/sensor/data/Image.h"
#include "carla/client/Sensor.h"
#include "rclcpp/rclcpp.hpp"
#include "carla_ros2_interface/msg/rpc_vehicle_control.hpp"

using namespace std::chrono_literals;
using namespace std::string_literals;


class ManualEgoCar : public rclcpp::Node
{
private:
    /* data */
    rclcpp::Subscription<carla_ros2_interface::msg::RpcVehicleControl>::SharedPtr __rpcVehcileControlSubscriber;
    // void __OnRecvRpcVehicleControl(const carla_ros2_interface::msg::RpcVehicleControl::SharedPtr rpc_vehicle_control);
    void __OnRecvSensorImageData(const carla::sensor::data::Image& image);
    void __OnRecvVehicleControlRequest(const carla_ros2_interface::msg::RpcVehicleControl::SharedPtr rpc_vehicle_control);

    // carla::client::Client __carlaClient;
    std::shared_ptr<carla::client::Client> __carlaClient;
    std::shared_ptr<carla::client::World> __carlaWorld;
    std::shared_ptr<carla::traffic_manager::ActorPtr> __carlaSpectator;
    boost::shared_ptr<carla::client::Vehicle> __vehicleModel3;
    boost::shared_ptr<carla::client::Sensor> __camRgb;
    rclcpp::Subscription<carla_ros2_interface::msg::RpcVehicleControl>::SharedPtr __rpcVehicleControlSubscriber;

public:
    ManualEgoCar(/* args */);
    ~ManualEgoCar();
};